package pub.tbc.hh.payment.domain;

import lombok.*;
import pub.tbc.toolkit.core.collect.Maps;

import java.util.Map;

import static pub.tbc.toolkit.core.EmptyUtil.nonEmpty;

/**
 * 微信统一下单调用接口，请求参数
 *
 * @auth tbc on 2018/5/11.
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WeixinUnifiedorderRequest {
    // 公众账号ID - 微信支付分配的公众账号ID（企业号corpid即为此appId）
//    @NonNull
    private String appid;
    // 商户号 微信支付分配的商户号
//    @NonNull
    private String mchId;
    // 设备号, 自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
    private String deviceInfo;    //否	String(32)	013467007045764
    // 随机字符串 - 长度要求在32位以内
//    @NonNull
    private String nonceStr;
    // 签名 - 通过签名算法计算得出的签名值，详见签名生成算法
//    @NonNull
//    private String sign;
    // 签名类型 - 默认为MD5，支持HMAC-SHA256和MD5。
//    private String sign_type; //	否	String(32)	MD5	签名类型，
//    private String signType; //	否	String(32)	MD5	签名类型，
    // 商品描述 - 商品简单描述，该字段请按照规范传递，具体请见参数规定, 如： 腾讯充值中心-QQ会员充值
//    @NonNull
    private String body;

    // 商品详情 - 商品详细描述，对于使用单品优惠的商户，改字段必须按照规范上传，详见“单品优惠参数说明”
    private String detail; //	否	String(6000)
    // 附加数据
    private String attach; ///	否	String(127)	深圳分店	附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。
    // 商户订单号 - 商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一。详见商户订单号
//    @NonNull
    private String outTradeNo;
    // 标价币种 - CNY	符合ISO 4217标准的三位字母代码，默认人民币：CNY，详细列表请参见货币类型
    private String feeType; //	否	String(16)
    @NonNull
    private int totalFee;
    // 终端IP - 123.12.12.123	APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。
//    @NonNull
    private String spbillCreateIp;
    // 交易起始时间
    private String timeStart;
    // 交易结束时间	建议：最短失效时间间隔大于1分钟
// 订单失效时间，格式为yyyyMMddHHmmss，如2009年12月27日9点10分10秒表示为20091227091010。
// 订单失效时间是针对订单号而言的，由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期，所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id。
    private String timeExpire;


    // 订单优惠标记
    private String goodsTag;//	否
    // 通知地址
    //	是	String(256)	http://www.weixin.qq.com/wxpay/pay.php	异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
    private String notifyUrl;
    // 交易类型
    // JSAPI 公众号支付 NATIVE 扫码支付 APP APP支付
    private String tradeType; //	是	String(16)

    // 商品ID
    //	否	String(32)	12235413214070356458058	trade_type=NATIVE时（即扫码支付），此参数必传。此参数为二维码中包含的商品ID，商户自行定义。
    private String productId;
    // 指定支付方式
    //	否	String(32)	no_credit	上传此参数no_credit--可限制用户不能使用信用卡支付
    private String limitPay;
    // 用户标识
    // trade_type=JSAPI时（即公众号支付），此参数必传，此参数为微信用户在商户对应appid下的唯一标识。
    // openid如何获取，可参考【获取openid】。企业号请使用【企业号OAuth2.0接口】获取企业号内成员userid，再调用【企业号userid转openid接口】进行转换
    private String openid; // 否 String(128)	oUpF8uMuAJO_M2pxb1Q9zNjWeS6o


    // 场景信息
    // 该字段用于上报场景信息，目前支持上报实际门店信息。该字段为JSON对象数据，对象格式为
    // {
    //     "store_info" : {
    //        "id": "SZTX001",
    //        "name": "腾大餐厅",
    //        "area_code": "440305",
    //        "address": "科技园中一路腾讯大厦" }
    // }
//    private String scene_info; //	否	String(256)
    private String sceneInfo;


    // ********************************************************************************* //
    //        方    法
    // ********************************************************************************* //

    private void map(Map<String, String> map, String fieldValue, String keyStr) {
        if (nonEmpty(fieldValue)) {
            map.put(keyStr, fieldValue);
        }
    }

    public Map<String, String> toMap() {
        Map<String, String> map = Maps.newHashMap();
        map(map, appid, "appid");
        map(map, mchId, "mch_id");
        map(map, deviceInfo, "device_info");
        map(map, nonceStr, "nonce_str");
//        String sign;
//        String signType; //	否
        map(map, body, "body");
        map(map, detail, "detail");
        map(map, attach, "attach");
        map(map, outTradeNo, "out_trade_no");
        map(map, feeType, "fee_type");
        if (totalFee > 0) {
            map.put("total_fee", Integer.toString(totalFee));
        }
        map(map, spbillCreateIp, "spbill_create_ip");
        map(map, timeStart, "time_start");
        map(map, timeExpire, "time_expire");
        map(map, goodsTag, "goods_tag");
        map(map, notifyUrl, "notify_url");
        map(map, tradeType, "trade_type");

        map(map, productId, "product_id");
        map(map, limitPay, "limit_pay");
        map(map, openid, "openid");
        return map;
    }



}
